# game_core.py (保持不变)
import json
import os
import pygame
from PIL import Image, ImageTk, ImageEnhance
from concurrent.futures import ThreadPoolExecutor
import threading


class GameCore:
    def __init__(self, resource_paths, screen_width, screen_height):
        self.resource_paths = resource_paths
        self.screen_width = screen_width
        self.screen_height = screen_height
        self.audio_executor = ThreadPoolExecutor(max_workers=4)
        self.init_audio()
        self.reset_state()

    def reset_state(self):
        """重置游戏状态"""
        self.current_chapter = 0
        self.current_dialogue = 0
        self.game_data = None
        self.backgrounds = {}
        self.characters = {}  # {char_id: {normal: img, dark: img}}
        self.character_sprites = {}  # {char_id: {sprite_name: img}}
        self.current_bgm = None
        self.sound_cache = {}
        self.bgm_volume = 0.5
        self.sfx_volume = 0.7
        self.ui_background_loaded = False
        self.ui_backgrounds = {}

    def init_audio(self):
        """初始化音频系统"""
        pygame.mixer.init(frequency=44100, size=-16, channels=2, buffer=2048)

    def load_game_data(self, chapter_file="chapter1.json"):
        """加载游戏剧本数据"""
        path = os.path.join(self.resource_paths["dialogues"], chapter_file)
        try:
            with open(path, "r", encoding="utf-8") as f:
                self.game_data = json.load(f)
                print(f"成功加载剧本: {chapter_file}")
        except FileNotFoundError:
            raise RuntimeError(f"剧本文件未找到: {path}")
        except json.JSONDecodeError as e:
            raise RuntimeError(f"JSON解析错误: {e}")

    def preload_resources(self):
        """预加载所有资源"""
        print("开始预加载资源...")
        self.preload_backgrounds()
        self.preload_characters()
        self.preload_sounds()
        self.load_ui_backgrounds()
        print("资源预加载完成")

    def preload_backgrounds(self):
        """预加载背景图片"""
        seen = set()
        for chapter in self.game_data["chapters"]:
            seen.add(chapter["background"])
            for dlg in chapter["dialogues"]:
                if "background" in dlg:
                    seen.add(dlg["background"])
        for bg in seen:
            self.load_background(bg)

    def load_background(self, filename):
        """加载单个背景图"""
        path = os.path.join(self.resource_paths["images"], filename)
        try:
            img = Image.open(path)
            self.backgrounds[filename] = ImageTk.PhotoImage(
                img.resize((self.screen_width, self.screen_height), Image.LANCZOS)
            )
            print(f"加载背景: {filename}")
        except Exception as e:
            print(f"加载背景失败: {filename}, 错误: {e}")
            # 创建占位背景
            placeholder = Image.new('RGB', (self.screen_width, self.screen_height), (50, 50, 100))
            self.backgrounds[filename] = ImageTk.PhotoImage(placeholder)

    def preload_characters(self):
        """预加载角色立绘"""
        for char_id, data in self.game_data["characters"].items():
            self.load_character(char_id, data["image"])

    def load_character(self, char_id, filename, is_sprite=False):
        """加载角色立绘"""
        path = os.path.join(self.resource_paths["images"], filename)
        try:
            print(f"尝试加载角色立绘: {char_id} - {filename}")
            img = Image.open(path).convert("RGBA")
            size = (int(self.screen_width * 0.2), int(self.screen_height * 0.5))

            # 生成正常状态 - 直接调整大小，不移除透明度
            normal = img.resize(size, Image.LANCZOS)

            # 存储立绘
            if not is_sprite:
                self.characters[char_id] = {
                    "normal": ImageTk.PhotoImage(normal),
                    "dark": None  # 简化，暂时不需要暗色状态
                }
                print(f"成功加载角色立绘: {char_id} - {filename}")
            else:
                if char_id not in self.character_sprites:
                    self.character_sprites[char_id] = {}
                self.character_sprites[char_id][filename] = ImageTk.PhotoImage(normal)
                print(f"成功加载角色特殊立绘: {char_id} - {filename}")

        except Exception as e:
            print(f"加载角色立绘失败: {filename}, 错误: {e}")
            # 为缺失的立绘提供占位符
            size = (int(self.screen_width * 0.2), int(self.screen_height * 0.5))
            placeholder = Image.new('RGBA', size, (255, 0, 0, 128))

            # 添加缺失的立绘文字提示
            from PIL import ImageDraw, ImageFont
            draw = ImageDraw.Draw(placeholder)
            try:
                # 尝试加载系统字体
                font = ImageFont.truetype("simhei.ttf", 24)
            except:
                # 使用默认字体
                font = ImageFont.load_default()

            draw.text((10, 10), f"缺失立绘: {filename}", font=font, fill=(255, 255, 255))

            placeholder_img = ImageTk.PhotoImage(placeholder)

            if not is_sprite:
                self.characters[char_id] = {
                    "normal": placeholder_img,
                    "dark": None
                }
            else:
                if char_id not in self.character_sprites:
                    self.character_sprites[char_id] = {}
                self.character_sprites[char_id][filename] = placeholder_img

    def preload_sounds(self):
        """预加载音频资源"""
        seen = set()
        for chapter in self.game_data["chapters"]:
            if "music" in chapter:
                seen.add(chapter["music"])
            for dlg in chapter["dialogues"]:
                if "sound" in dlg:
                    seen.add(dlg["sound"])
        for sound in seen:
            if sound:  # 确保不为空
                self.load_sound(sound)

    def load_sound(self, filename, bgm=False):
        """加载音频到缓存"""
        if filename in self.sound_cache or not filename:
            return
        path = os.path.join(self.resource_paths["sounds"], filename)
        try:
            if bgm:
                self.sound_cache[filename] = path
            else:
                sound = pygame.mixer.Sound(path)
                sound.set_volume(self.sfx_volume)
                self.sound_cache[filename] = sound
            print(f"加载音效: {filename}")
        except Exception as e:
            print(f"加载音效失败: {filename}, 错误: {e}")
            self.sound_cache[filename] = None

    def play_sound(self, filename, loops=0):
        """播放音效"""

        def _play():
            sound = self.sound_cache.get(filename)
            if sound and isinstance(sound, pygame.mixer.Sound):
                sound.play(loops=loops)

        self.audio_executor.submit(_play)

    def play_bgm(self, filename):
        """播放背景音乐"""

        def _play():
            if self.current_bgm == filename:
                return
            path = self.sound_cache.get(filename)
            if path:
                pygame.mixer.music.load(path)
                pygame.mixer.music.set_volume(self.bgm_volume)
                pygame.mixer.music.play(-1)
                self.current_bgm = filename
                print(f"播放背景音乐: {filename}")
            else:
                pygame.mixer.music.stop()  # 停止当前音乐
                self.current_bgm = None

        self.audio_executor.submit(_play)

    def load_ui_backgrounds(self):
        """加载UI背景图片"""
        try:
            ui_bg_path = os.path.join(self.resource_paths["images"], "云墨青山.jpg")
            ui_bg = Image.open(ui_bg_path)

            # 创建对话框背景
            dialogue_box_height = int(self.screen_height * 0.2)
            dialogue_box_width = int(self.screen_width * 0.9)
            crop_y_start = max(0, ui_bg.height - dialogue_box_height * 3)
            dialogue_crop = ui_bg.crop((0, crop_y_start, ui_bg.width, crop_y_start + dialogue_box_height))
            dialogue_resized = dialogue_crop.resize((dialogue_box_width, dialogue_box_height), Image.LANCZOS)

            # 添加半透明遮罩
            dialogue_mask = Image.new('RGBA', dialogue_resized.size, (0, 0, 0, 128))
            dialogue_with_mask = Image.alpha_composite(dialogue_resized.convert('RGBA'), dialogue_mask)
            self.ui_backgrounds["dialogue_box"] = ImageTk.PhotoImage(dialogue_with_mask)

            # 创建按钮背景
            button_width = 300
            button_height = 80
            button_crop = ui_bg.crop((0, 0, min(ui_bg.width, button_width), min(ui_bg.height, button_height)))
            button_resized = button_crop.resize((button_width, button_height), Image.LANCZOS)

            # 正常状态和悬停状态
            button_mask = Image.new('RGBA', button_resized.size, (0, 0, 0, 128))
            button_with_mask = Image.alpha_composite(button_resized.convert('RGBA'), button_mask)
            self.ui_backgrounds["button_normal"] = ImageTk.PhotoImage(button_with_mask)

            button_hover = button_with_mask.copy()
            hover_mask = Image.new('RGBA', button_resized.size, (255, 255, 255, 30))
            button_hover = Image.alpha_composite(button_hover, hover_mask)
            self.ui_backgrounds["button_hover"] = ImageTk.PhotoImage(button_hover)

            self.ui_background_loaded = True
            print("UI背景加载成功")

        except Exception as e:
            print(f"UI背景加载失败: {e}")
            self.ui_background_loaded = False

    def cleanup(self):
        """清理资源"""
        self.audio_executor.shutdown()
        pygame.mixer.quit()
